公司主页 文档归类 淘宝

BLE连接参数更新过程详解

有关连接参数概念和作用我们在 Generic Access Profile (GAP) 一章中已经详细讲解过,这一章演示如何通过修改simple_peripheral例程实现连接参数更新,并分析程序流程。

介绍

连接参数更新过程中都是主机发起的,从机只能被动的接收主机设置的参数,这个过程发生在连接的时候,当连接之后如果主机设置的参数不利于从机,从机可以发送请求,请求中包含需要的连接参数,从机请求主机重新更新连接参数,主机可以拒绝,如果主机同意修改连接参数,并且参数合理,则主机发起连接参数更新,如果参数不合理(例如主机不支持过大或者过小的连接间隔),则主机会对参数进行协商,选择最合理的参数进行设置。由于从机发起连接参数更新请求的过程包含了主机发起连接参数更新的过程。本文以simple_peripheral工程为例,演示由从机发起连接参数更新请求的过程。

硬件环境

使用USB连接CC2640R2F Evaluation Board。确保跳线帽正确连接,如下图所示

软件环境

协议栈和IAR安装以及我们工程编译参考CC2640R2 BLE 开发环境搭建 编译参考 编译第一个工程(simple_peripheral),有关BTool使用请参考BTool。 有关Packet Sniffer使用请参考 Packet Sniffer 。所有工具可以在CC2640R2开发工具集介绍里获得。

运行流程

  1. 在simple_perpheral中可以选择使用按键和定时器的方式进行连接参数更新,这里我们使用定时器的方式进行连接参数更新,并且对定时器启动过程进行分析。
    在peripheral.c文件中,定义了startUpdateClock的结构体变量,startUpdateClock作为连接参数更新的定时器事件句柄。在gapRole_init()中,可以找到其初始化过程。Util_constructClock(&startUpdateClock, gapRole_clockHandler,0, 0, false, START_CONN_UPDATE_EVT);

2.在gapRole_processGAPMsg中,GAP_LINK_ESTABLISHED_EVENT事件的处理过程里面可以看见

//source\ti\ble5stack\profiles\roles\cc26xx\peripheral.c  GAP_LINK_ESTABLISHED_EVENT Line 1195
uint16_t timeout = GAP_GetParamValue(TGAP_CONN_PAUSE_PERIPHERAL);

Util_restartClock(&startUpdateClock, timeout*1000);

所以当一旦连接建立,就启动该定时器,这里timeout通过GAP_GetParamValue得到。在SimpleBLEPeripheral_init函数中,通过下面代码段已经设置了DEFAULT_CONN_PAUSE_PERIPHERAL值。

//examples\rtos\CC2640R2_LAUNCHXL\ble5stack\simple_peripheral\src\app\simple_peripheral.c DEFAULT_CONN_PAUSE_PERIPHERAL  Line 144
// Connection Pause Peripheral time value (in seconds)
#define DEFAULT_CONN_PAUSE_PERIPHERAL         6
GAP_SetParamValue(TGAP_CONN_PAUSE_PERIPHERAL, DEFAULT_CONN_PAUSE_PERIPHERAL);

当定时器时间到达后,调用下面回调函数,并传入初始化中设置的START_CONN_UPDATE_EVT参数,可以看出,该回调函数仅发送了一个事件。

//source\ti\ble5stack\profiles\roles\cc26xx\peripheral.c  gapRole_clockHandler Line 1626
void gapRole_clockHandler(UArg a0)
{
  gapRole_setEvent(a0);
}

然后在gapRole_taskFxn函数中进行相应事件处理。这里调用gapRole_startConnUpdate函数进行连接参数更新。

//source\ti\ble5stack\profiles\roles\cc26xx\peripheral.c  gapRole_taskFxn Line 895
if (events & START_CONN_UPDATE_EVT)
{
// Start connection update procedure
gapRole_startConnUpdate(GAPROLE_NO_ACTION, &gapRole_updateConnParams);
}

而在simple_peripheral.c中使用以下函数端对连接参数变量进行赋值。其中需要特别注意DEFAULT_ENABLE_UPDATE_REQUEST。需要在其 定义处修改成GAPROLE_LINK_PARAM_UPDATE_INITIATE_BOTH_PARAMS。这样双方都可以启动连接参数更新过程。

//examples\rtos\CC2640R2_LAUNCHXL\ble5stack\simple_peripheral\src\app\simple_peripheral.c enableUpdateRequest line 510
uint8_t enableUpdateRequest = DEFAULT_ENABLE_UPDATE_REQUEST;
uint16_t desiredMinInterval = DEFAULT_DESIRED_MIN_CONN_INTERVAL;
uint16_t desiredMaxInterval = DEFAULT_DESIRED_MAX_CONN_INTERVAL;
uint16_t desiredSlaveLatency = DEFAULT_DESIRED_SLAVE_LATENCY;
uint16_t desiredConnTimeout = DEFAULT_DESIRED_CONN_TIMEOUT;
  1. 上述过程理解清楚后,我们就可以在peripheral.c文件中直接修改连接参数,在更新的时候使用我们自己设置的连接参数。
//examples\rtos\CC2640R2_LAUNCHXL\ble5stack\simple_peripheral\src\app\simple_peripheral.c DEFAULT_DESIRED_MAX_CONN_INTERVAL line 118
#define DEFAULT_DESIRED_MAX_CONN_INTERVAL     500
#define DEFAULT_DESIRED_CONN_TIMEOUT          2500
#define DEFAULT_DESIRED_SLAVE_LATENCY         1

下图是使用BTool建立连接之后等待6秒收到的数据。可以看出在连接的时候使用的是主机端设置的连接参数。ConnInterval=80,ConnLatency=0,ConnTimout=2000。建立连接6秒之后,启动连接参数更新,并且更新为设置的 ConnInterval=500,ConnLatency=1,ConnTimout=2500。

下面我们使用Packet Sniffer抓包分析一下流程:如图示首先定时器时间到达之后,由从机向主机(S->M)发送连接参数更新请求命令,并携带更新参数值,主机接收到之后有权利拒绝本次更新,这里主机返回0X0000(M->S),表示同意本次连接参数更新。随后主机端会根据从机的参数进行一次协商,如果从机设置的参数不满足主机端设置的最大值或最小值,则主机会设置当前支持的最大值,举个例子,如果这里我们把DEFAULT_DESIRED_CONN_TIMEOUT改成一个比较小的数值,主机端可能就不会使用我们设定的值。而使用主机端所能支持的最小值。所以最后主机发送协商之后最终使用的连接参数(M->S)。从机接收并更新后返回应答响应。

//source\ti\ble5stack\inc\l2cap.h L2CAP_CONN_PARAMS_ACCEPTED line 210
#define L2CAP_CONN_PARAMS_ACCEPTED       0x0000 //!< Connection Parameters accepted
#define L2CAP_CONN_PARAMS_REJECTED       0x0001 //!< Connection Parameters rejected

下面是连接过程中,由主机直接发起的连接参数更新请求,可以看出如果是主机直接修改连接参数,只需要发送连接参数更新请求。从机返回响应之后即完成了连接参数更新。

加入我们

文章所有代码、工具、文档开源。加入我们QQ群 591679055获取更多支持,共同研究CC2640R2F&BLE5.0。

CC2640R2F&BLE5.0-乐控畅联 © Copyright 2017, 成都乐控畅联科技有限公司.